/**	\file		Converter.h
*	\author 	Abbas Bazzi
*	\author  	Farah Charab
*	\author		Rafah El-Khatib
*	\brief		A header file that uses the Adapter Design Pattern to Translate from PianoGraph to Zgraph, the given target graph,  and vice versa, where PianoGraph is the 	   *  Graph of our language.
*/


#ifndef _CONVERTER_H_
#define _CONVERTER_H_
#include "Zgraph.h"
#include "RealGraph.h"
#include "Graph.h"
#include <string>
#include<iostream>
#include <sstream>
using namespace std;

/**	\typedef	GraphStructTwo
*	\param		Two strings that constitute the basic entities of the type ProgGraph
*	\brief		Target graph structure
*/
typedef ProgGraph <string, string> GraphStructTwo;
/**	\typedef	GraphStructOne
*	\brief		Initial graph structure
*/
typedef RealGraph GraphStructOne;
/**	\typedef	Stmt
*	\brief		Member of GraphStructTwo. A structure that represents a statement in the target graph.
*/
typedef GraphStructTwo::ProgStmt Stmt;
/**	\typedef	Expr
*	\brief		Member of GraphStructTwo. A structure that represents an expression in the target graph.
*/
typedef GraphStructTwo::ProgExpr Expr;
/**	\typedef	Var
*	\brief		Member of GraphStructTwo. A structure that represents a variable in the target graph.
*/
typedef GraphStructTwo::ProgVar Var;
/**	\typedef	Lit
*	\brief		Member of GraphStructTwo. A structure that represents a literal in the target graph.
*/
typedef GraphStructTwo::ProgLit Lit;
/**	\typedef	Edge
*	\brief		Member of GraphStructTwo. A structure that represents an edge in the target graph.
*/
typedef GraphStructTwo::ProgEdge Edge;
/**	\typedef	ProgEdgeIter
*	\brief		Iterator for an edge in the target graph.
*/
typedef list<Edge*>::iterator ProgEdgeIter;
/**	\typedef	Znode
*	\brief		Member of GraphStructTwo. A structure that represents a node in the target graph.
*/
typedef GraphStructTwo::ProgNode Znode;
/**	\typedef	NodesVector
*	\brief		A vector of nodes, each having a node structure as declared in the target graph structure.
*/
typedef vector <Znode *> NodesVector;
/**	\typedef	MapFromStringToIndex
*	\param		A string to index the map.
*	\brief		Map from string to integer, where the integer will represent a certain index.
*/
typedef map <string,int> MapFromStringToIndex;
/**	\typedef	MapFromIndextoString
*	\param		An integer to index the map.
*	\brief		Map from integer to integer, where the integer will represent a certain index.
*/
typedef map <int,string> MapFromIndextoString;
/**	\typedef	MapFromNodeToIndex
*	\param		A node of the target graph to index the map.
*	\brief		Map from a node to an integer, where the node has a node structure as declared in the target graph, and the integer represents a certain index
*/
typedef map <Znode*,int> MapFromNodeToIndex;

/**	\class		AdapterGraph
*	\brief		Base Class which contains functions used to construct general graphs and convert from one structure to the other. It will be used by inheritance by other classes to construct specific graphs or implement different translations between different structures of graphs.It contains three public functions: conversion of graph, adding a node, and adding an edge.
*/
class AdapterGraph{
	public:
		void ConvertGraphStructure();
		void AddNode();
		void AddEdge();
};

/**	\class		GraphStructureOne
*	\brief		Class that inherits from AdapterGraph. It takes care of converting the structure Zgraph into the structure constructed in Graph.h and RealGraph.h.
*/
class GraphStructureOne :public AdapterGraph{
public:
  	GraphStructOne Agraph;//!< Instance of the class we are inside called Agraph. This is the target graph in this class.
/**	\fn		void AddNode(Znode* b, int i);
*	\param		b A pointer to a node of type Zgraph, the given target graph.
*	\param		i A integer which is used to map a node to an index in the corresponding map.
*	\brief		This function uses the interface of Piano Graph Structure to add a node.
*/   
	void AddNode(Znode* b,int i);
/**	\fn		void AddEdge(Znode* b,int i);
*	\param		b A pointer to a node of type Zgraph, the given target graph.	
*	\param		i A integer which is used to map the soucre of the edge going to b to and index.
*	\brief		This function uses the interface of of Piano Graph Structure to add an edge.
*/
	void AddEdge(Znode* b,int i);
/**	\fn		void ConvertGraphStructure(GraphStructTwo & b);
*	\param		b Zgraph passed by reference.
*	\brief		This function uses the functions addEdge and AddNode of the Class GraphStructureOne to convert Piano Graph to Zgraph.	
*/
	void ConvertGraphStructure(GraphStructTwo & b);
			
private:
	MapFromNodeToIndex NodeToIndex;//!< This is a Map from string to integer, where it maps distint nodes of Piano Graph to distint indices.
};
/**	\class		GraphStructureTwo
*	\brief		Class that inherits from AdapterGraph. It takes care of converting the structure Real Graph to Zgraph, the given target graph.	
*/
class GraphStructureTwo: public AdapterGraph{
public:
	GraphStructTwo Bgraph;//!< Instance of the class we are inside called Bgraph. This is the target graph in this class.
/*!	\fn		void AddNode(NODE node,int i)
*	\param		node A node belonging to Piano Graph, our constructed graph.
*	\param		i An integer which is used to map a node to an index using the corresponding map.
*	\brief		This function uses the interface of Zgraph, the given target graph, to add a node.
*/
	void AddNode(NODE node,int i);
/*!	\fn 		void AddEdge(Znode* b,int i);
*	\param		edge An edge belonging to Piano Graph, our constructed graph.
*	\brief		This function uses the interface of the ZGraph, the given target graph, to add an edge.
*/
	void AddEdge(EDGE edge);
/*!	\fn		void ConvertGraphStructure(GraphStructTwo & b);
*	\param		b Real Graph passed by reference.	
*	\brief		This function uses the functions addEdge and AddNode of the Class GraphStructureTwo to convert Piano Graph to Zgraph.
*/
	void ConvertGraphStructure(GraphStructOne & b);
private:
	NodesVector StructureTwoNodes;//!< A structure that holds the nodes of the target graph.
	MapFromStringToIndex NodeIndex;//!< A map from strings to integers that maps distinct nodes of the target graph, Zgraph, to distinct indices.
};

#endif
